<template>
  <div class="view">
    <Palette ref="palette" @revert="revert()" @clear="clear()"></Palette>
    <canvas
      id="mycanvas"
      ref="mycanvas"
      :width="cWidth"
      :height="cHeight"
      @mousedown="mouseDown"
    ></canvas>
  </div>
</template>

<script>
import Palette from "@/components/Palette";

export default {
  name: "myy-screen-paint",
  components: {
    Palette,
  },
  props:{
    cWidth:Number,
    cHeight:Number
  },
  data() {
    return {
      brush: null,
      _x: 0, //上一次绘制x
      _y: 0,
      _canvas: null,
      _ctx: null,
      _imageData: null, //最新保存的图层数据
      dataHistory: [], //历史图层数据
    };
  },
  created() {
    this.$nextTick((_) => {
      this.init();
      window.addEventListener("resize", (_) => {
        //todo canvas大小变化
        // this.canvasCopy();
        // this._canvas.width = window.innerWidth;
        // this._canvas.height = window.innerHeight;
        // this.canvasPaste();
      });
    });
  },
  methods: {
    init() {
      this._canvas = this.$refs.mycanvas;
      this._ctx = this._canvas.getContext("2d");
      this.canvasCopy();
      this.dataHistory.push(this._imageData);
    },
    getBrushProp() {
      let prop = this.$refs.palette.getBrushProp();
      return prop;
    },
    revert() {
      console.log("revert :>> ");
      let revertData = this.dataHistory[this.dataHistory.length - 2];
      this._ctx.putImageData(revertData, 0, 0);
      if (this.dataHistory.length > 1) {
        this.dataHistory.pop();
      }
    },
    drawRound(newX, newY) {
      this._ctx.strokeStyle = this.brush.color.color;
      this._ctx.lineWidth = this.brush.size.size;
      let centerX = this._x + (newX - this._x) / 2;
      let centerY = this._y + (newY - this._y) / 2;
      let r1 = Math.abs((newX - this._x) / 2);
      let r2 = Math.abs((newY - this._y) / 2);
      this._ctx.beginPath();
      // 绘制圆的路径**
      this._ctx.ellipse(centerX, centerY, r1, r2, 0, 0, Math.PI * 2, false);
      // 描边路径
      this._ctx.stroke();
    },
    drawRect(newX, newY) {
      let startX = Math.min(this._x, newX);
      let startY = Math.min(this._y, newY);
      let shapeW = Math.abs(this._x - newX);
      let shapeH = Math.abs(this._y - newY);
      this._ctx.strokeStyle = this.brush.color.color;
      this._ctx.lineWidth = this.brush.size.size;
      this._ctx.strokeRect(startX, startY, shapeW, shapeH);
    },
    drawCloud(newX, newY) {
      this._ctx.strokeStyle = this.brush.color.color;
      this._ctx.lineWidth = this.brush.size.size;
      this._ctx.lineTo(newX, newY);
      this._ctx.stroke();
    },
    drawArrow(newX, newY) {
      this._ctx.fillStyle = this.brush.color.color;
      this._ctx.lineWidth = this.brush.size.size;
      let [x1, x2, y1, y2] = [this._x, newX, this._y, newY];
      let w = x2 - x1,
        h = y2 - y1,
        sh = Math.cos(Math.PI / 4) * 16;
      let sin = h / Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));
      let cos = w / Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));
      let w1 = (16 * sin) / 4,
        h1 = (16 * cos) / 4,
        centerx = sh * cos,
        centery = sh * sin;
      this._ctx.beginPath();
      this._ctx.moveTo(x1, y1);
      this._ctx.lineTo(x2 - centerx + w1, y2 - centery - h1);
      this._ctx.lineTo(x2 - centerx + w1 * 2, y2 - centery - h1 * 2);
      this._ctx.lineTo(x2, y2);
      this._ctx.lineTo(x2 - centerx - w1 * 2, y2 - centery + h1 * 2);
      this._ctx.lineTo(x2 - centerx - w1, y2 - centery + h1);
      this._ctx.closePath();
      this._ctx.fill();
    },
    drawText(input) {
      if (input.value) {
        let fontSize = 0;
        switch (this.brush.size.name) {
          case "小":
            fontSize = 14;
            break;
          case "中":
            fontSize = 18;
            break;
          case "大":
            fontSize = 22;
            break;
        }
        let x = parseInt(input.style.left.replace("px", ""));
        let y = parseInt(input.style.top.replace("px", ""));
        this._ctx.font = fontSize + 'px "微软雅黑"';
        this._ctx.fillStyle = this.brush.color.color;
        this._ctx.textBaseline = "top";
        let strLines = input.value.split("\n");
        strLines.forEach((txt, index) => {
          let newY = y + index * fontSize;
          this._ctx.fillText(txt, x, newY);
        });
        this.canvasCopy();
        this.dataHistory.push(this._imageData);
      }
      this.$nextTick((_) => {
        if (document.getElementById("input_temp")) {
          input.remove();
        }
      });
    },
    clear() {
      this.dataHistory.push(this._imageData);
      this._canvas.height = this._canvas.height;
    },
    prePaint() {
      switch (this.brush.tool.label) {
        case "text":
          let tmpInput = document.getElementById("input_temp");
          //插入临时输入框
          if (tmpInput) {
            tmpInput.remove();
          } else {
            let input = document.createElement("textarea");
            input.setAttribute("id", "input_temp");
            input.style = "position:fixed";
            input.style.top = this._y + "px";
            input.style.left = this._x + "px";
            input.style.zIndex = 3000;
            input.style.background = "transparent";
            input.style.color = this.brush.color.color;
            input.style.height = "auto";
            input.style.padding = "6px";
            input.style.borderColor = "1px solid red";
            switch (this.brush.size.name) {
              case "小":
                input.style.fontSize = "14px";
                break;
              case "中":
                input.style.fontSize = "18px";
                break;
              case "大":
                input.style.fontSize = "22px";
                break;
            }
            input.addEventListener("propertychange", (e) => {
              input.style.height = input.scrollHeight + "px";
            });
            input.addEventListener("keydown", (e) => {
              var evt = window.event || e;
              if (evt.keyCode == 27) {
                this.drawText(e.target);
              } else if (evt.keyCode == 13) {
              }
            });
            input.addEventListener("blur", (e) => {
              this.drawText(e.target);
            });
            document.body.appendChild(input);
            input.focus();
          }
          break;
        case "cloud":
          this._ctx.beginPath();
          this._ctx.moveTo(this._x, this._y);
          break;
      }
    },
    paint(newX, newY) {
      switch (this.brush.tool.label) {
        case "rect":
          this.canvasPaste();
          this.drawRect(newX, newY);
          break;
        case "round":
          this.canvasPaste();
          this.drawRound(newX, newY);
          break;
        case "cloud":
          this.drawCloud(newX, newY);
          break;
        case "arrow":
          this.canvasPaste();
          this.drawArrow(newX, newY);
          break;
        case "text":
          break;
      }
    },
    afterPaint() {
      switch (this.brush.tool.label) {
        case "text":
          break;
        // case "cloud":
        //   break
        default:
          this.canvasCopy();
          this.dataHistory.push(this._imageData);
          break;
      }
    },
    mouseDown(e) {
      this.canvasCopy();
      this.brush = this.getBrushProp();
      let vm = this;
      let el = this.$refs.mycanvas;
      this._x = e.clientX;
      this._y = e.clientY;

      el.setCapture //捕捉焦点
        ? (el.setCapture(),
          //设置事件
          (el.onmousemove = (ev) => {
            vm.dragMove(ev || event);
          }),
          (el.onmouseup = vm.dragUp))
        : //绑定事件
          (document.addEventListener("mousemove", vm.mouseMove),
          document.addEventListener("mouseup", vm.mouseUp));
      //防止默认事件发生
      e.preventDefault();
      this.prePaint();
    },
    mouseMove(e) {
      let newX = e.clientX;
      let newY = e.clientY;
      this.paint(newX, newY);
    },
    mouseUp(e) {
      try {
        let el = this.$refs.mycanvas;
        let vm = this;
        if (el) {
          el.releaseCapture
            ? //释放焦点
              (el.releaseCapture(),
              //移除事件
              (el.onmousemove = el.onmouseup = null))
            : //卸载事件
              (document.removeEventListener("mousemove", vm.mouseMove),
              document.removeEventListener("mouseup", vm.mouseUp));
        }

        this.afterPaint();
      } catch (ex) {}
    },
    //画布数据保存
    canvasCopy() {
      var width = this._ctx.canvas.width;
      var height = this._ctx.canvas.height;
      this._imageData = this._ctx.getImageData(0, 0, width, height);
    },
    //画布数据恢复
    canvasPaste() {
      this._ctx.putImageData(this._imageData, 0, 0);
    },
  },
};
</script>

<style lang="less" scoped>
.view {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2000;
  canvas {
    width: 100%;
    height: 100%;
    background: transparent;
  }
}
</style>